package edu.scs.ubbcluj.view;

import edu.scs.ubbcluj.backend.Join;
import edu.scs.ubbcluj.backend.MongoDB;
import edu.scs.ubbcluj.backend.Selection;
import edu.scs.ubbcluj.model.Attribute;
import edu.scs.ubbcluj.model.Condition;
import edu.scs.ubbcluj.model.Database;
import edu.scs.ubbcluj.model.Databases;
import edu.scs.ubbcluj.model.ForeignKey;
import edu.scs.ubbcluj.model.Table;
import edu.scs.ubbcluj.xml.JDom;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javafx.application.Application;
import javafx.beans.property.SimpleStringProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.Event;
import javafx.event.EventHandler;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.control.Tab;
import javafx.scene.control.TabPane;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.TreeCell;
import javafx.scene.control.TreeItem;
import javafx.scene.control.TreeView;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.scene.text.Font;
import javafx.stage.Stage;
import javafx.util.Callback;

import javassist.CannotCompileException;
import org.apache.commons.lang3.SerializationUtils;

public class MainTreeView extends Application {

    private final Node rootIcon
            = new ImageView(new Image(getClass().getResourceAsStream("dbs.png")));
    private final Image dbIcon = new Image(getClass().getResourceAsStream("root1.png"));
    private final Image tableIcon
            = new Image(getClass().getResourceAsStream("tableicon_1.png"));
    private final Image attrIcon
            = new Image(getClass().getResourceAsStream("dot_1.jpg"));
    private Databases dbs;
    private TreeView treeView;
    private JDom dom;
    

    public static void main(String[] args) {
        Application.launch(args);
    }

    public void loadData() {
        dom = new JDom();
        dbs = dom.loadFromXml();
    }

    @Override
    public void start(Stage stage) {
        MongoDB.connectToMongo();

        loadData();
        TreeItem rootNode = new TreeItem(dbs, rootIcon);

        rootNode.setExpanded(true);

        for (Database db : dbs.getDatabases()) {
            TreeItem node = new TreeItem(db, new ImageView(dbIcon));

            rootNode.getChildren().add(node);

            for (Table table : db.getTables()) {

                TreeItem depNode = new TreeItem(table,
                        new ImageView(tableIcon)
                );
                node.getChildren().add(depNode);
                for (Attribute attr : table.getPrimaryKeys()) {
                    TreeItem attrLeaf = new TreeItem(attr,
                            new ImageView(attrIcon)
                    );
                    depNode.getChildren().add(attrLeaf);
                }
                for (ForeignKey attr : table.getForeignKeys()) {
                    TreeItem attrLeaf = new TreeItem(attr,
                            new ImageView(attrIcon)
                    );
                    depNode.getChildren().add(attrLeaf);
                }
                for (Attribute attr : table.getAttributes()) {
                    TreeItem attrLeaf = new TreeItem(attr,
                            new ImageView(attrIcon)
                    );
                    depNode.getChildren().add(attrLeaf);
                }

            }
        }

        stage.setTitle("Tree View Sample");
        VBox box = new VBox();
        final Scene scene = new Scene(box, 400, 300);
        scene.setFill(Color.LIGHTGRAY);

        treeView = new TreeView(rootNode);
        treeView.setEditable(true);
        treeView.setCellFactory(new Callback<TreeView, TreeCell>() {
            @Override
            public TreeCell<String> call(TreeView p) {
                return new AddItem(dbs);
            }
        });

        box.getChildren().add(treeView);
        
        stage.setScene(scene);
        stage.setOnCloseRequest(new EventHandler() {

            @Override
            public void handle(Event t) {
                dom.saveToXml(dbs);
            }
        });
        stage.show();
        testSelection();
    }

    public void testSelection(){
        Database db = Util.getDBByName(dbs.getDatabases(), "University");
        MongoDB.setDatastore(db);
        Table table = Util.getTableByName(db.getTables(), "Student");
        
        Condition cond = new Condition(Util.getAttributeByName(table.getAttributes(), "Name"), "equal","Istvan");
        Condition cond2 = new Condition(Util.getAttributeByName(table.getAttributes(), "Mark"), ">","7");
        List<Condition> conditions = new ArrayList();
        conditions.add(cond);
        conditions.add(cond2);
        List<Attribute> wantedAttrs = table.getAttributes();
        List<List<String>> result = Selection.getMatchingRows(table, conditions, wantedAttrs);
        for (List<String> row:result){
            for (String v:row){
                System.out.print(v + " ");
            }
            System.out.println();
        }
        System.out.println("Sorted elements:");
        Attribute groupOne = Util.getAttributeByName(wantedAttrs, "Name");
        result = Selection.oderBy(MongoDB.getAll(table), table, groupOne, "ASC");
        for (List<String> row:result){
            for (String v:row){
                System.out.print(v + " ");
            }
            System.out.println();
        }
        Attribute theOne = Util.getAttributeByName(wantedAttrs, "Mark");
        System.out.println("Group by name:");
        //result = Selection.groupBy(table, groupOne, theOne,"SUM", null, null, null);
        //result = Selection.groupBy(MongoDB.getAll(table), table, groupOne, theOne,"SUM", "SUM", ">", "15");
        //result = Selection.groupBy(table, groupOne, theOne,"AVG", null, null, null);
        //result = Selection.groupBy(table, groupOne, theOne,"COUNT", null, null, null);
        /*for (List<String> row:result){
            for (String v:row){
                System.out.print(v + " ");
            }
            System.out.println();
        }*/
        
        Table table1Original = Util.getTableByName(db.getTables(), "Diak");
        Table table1 = SerializationUtils.clone(table1Original);
        Table table2Original = Util.getTableByName(db.getTables(), "Csoport");
        Table table2 = SerializationUtils.clone(table2Original);
        Attribute join1 = Util.getAttributeByName(table1Original.getAttributes(), "csopkod");
        Attribute join2 = Util.getAttributeByName(table2Original.getAttributes(), "Kod");
        result = Join.indexedNestedLoop(table1,table1Original, join1, table2, table2Original, join2);
        System.out.println("The join");
        for (List<String> row:result){
            for (String v:row){
                System.out.print(v + " ");
            }
            System.out.println();
        }
        
        result = Join.mergeJoin(table1Original, join1, table2Original, join2);
        System.out.println("The join2:");
        for (List<String> row:result){
            for (String v:row){
                System.out.print(v + " ");
            }
            System.out.println();
        }
    }
    
}
